package com.yoke.controller.shield;

import com.alibaba.fastjson.JSONObject;
import com.yoke.common.base.AbstractBaseControl;
import com.yoke.common.interceptor.NotLogin;
import com.yoke.ip.IpUtil;
import com.yoke.shield.ShieldUtil;
import com.yoke.system.log.SystemLog;
import com.yoke.util.StringUtil;
import org.dom4j.DocumentException;
import org.springframework.context.annotation.Scope;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.WebApplicationContext;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;

/**
 * Created by jiangzeyin on 2017/9/7.
 */
@Controller
@Scope(value = WebApplicationContext.SCOPE_SESSION)
@RequestMapping("shield")
public class ShieldIpController extends AbstractBaseControl {

    private static final HashMap<String, JSONObject> JSON_HASH_MAP = new HashMap<>();
    //private static final HashMap<String, Long> UPDATE_TIME = new HashMap<>();
    // ip 地址缓存时间
    //private static final long CACHE_TIME = 10 * 60 * 60 * 1000;
    // 读取文件信息缓存时间
    // private static final long FILE_CACHE_TIME = 5 * 60 * 1000;

    private static JSONObject getJson(String id) throws IOException {
        JSONObject jsonObject = JSON_HASH_MAP.get(id);
        if (jsonObject == null) {
            jsonObject = ShieldUtil.getObjById(id);
            if (jsonObject == null) {
                return null;
            }
            JSON_HASH_MAP.put(id, jsonObject);
        }
        return jsonObject;
    }

    private String do_(String id, String cache, String showInfo, String to) {
        if (!StringUtil.IsEmpty(showInfo)) {
            // 查看当前屏蔽信息
            JSONObject cacheObj = JSON_HASH_MAP.get(id);
            request.setAttribute("cache", cacheObj);
            try {
                JSONObject fileObj = ShieldUtil.getObjById(id);
                request.setAttribute("file", fileObj);
            } catch (IOException e) {
                SystemLog.ERROR().error("文件", e);
            }
            request.setAttribute("ipCount", IpUtil.getCaCheSize(id));
            return "../shield/info";
        }
        // 收到手动清理缓存
        if (!StringUtil.IsEmpty(cache)) {
            JSON_HASH_MAP.remove(id);
            IpUtil.clearCache(id);
            SystemLog.LOG().info(ip + " 执行 " + id + " 清空缓存");
        }
        // 指定显示
        if ("can".equals(to)) {
            return "../shield/" + id + "/can";
        }
        if ("noCan".equals(to)) {
            return "../shield/" + id + "/notCan";
        }
        JSONObject jsonObject;
        try {
            jsonObject = getJson(id);
        } catch (IOException e) {
            SystemLog.ERROR().error("获取异常", e);
            request.setAttribute("msg", "error");
            return "../shield/error";
        }
        if (jsonObject == null) {
            request.setAttribute("msg", "id 为null");
            return "../shield/error";
        }
        boolean flag;
        try {
            flag = IpUtil.isCan(ip, jsonObject, isMobile(request));
        } catch (IOException | DocumentException e) {
            SystemLog.ERROR().error("ip解析异常", e);
            request.setAttribute("msg", "解析异常");
            return "../shield/error";
        }
        return flag ? ("../shield/" + id + "/can") : ("../shield/" + id + "/notCan");
    }

    @RequestMapping(value = "{id}/{path}", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    @NotLogin
    public String to(@PathVariable String id, @PathVariable String path, String cache, String showInfo, String to) {
        return do_(id, cache, showInfo, to);
    }

    @RequestMapping(value = "{id}", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    @NotLogin
    public String to(@PathVariable String id, String cache, String showInfo, String to) {
        return do_(id, cache, showInfo, to);
    }

    /**
     * 接口清理缓存
     *
     * @param id id
     * @return 结果
     */
    @RequestMapping(value = "opt", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @NotLogin
    @ResponseBody
    public String opt(String id) {
        IpUtil.remove(id);
        JSON_HASH_MAP.remove(id);
        SystemLog.LOG().info("接口清空：" + id + " 缓存");
        return "ok";
    }

    private final static String[] agent = {"Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser"};

    private static boolean isMobile(HttpServletRequest request) {
        String ua = request.getHeader("user-agent");
        boolean flag = false;
        if (ua == null)
            return false;
        if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;"))) {
            // 排除 苹果桌面系统
            if (!ua.contains("Windows NT") && !ua.contains("Macintosh")) {
                for (String item : agent) {
                    if (ua.contains(item)) {
                        flag = true;
                        break;
                    }
                }
            }
        }
        return flag;
    }

}
